﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using RobotGameData;

namespace RobotGame
{
    public class MapEngine
    {
        // map
        private Map map;

        public Map Map
        {
            get { return map; }
            set { map = value; }
        }

        private Viewport viewport;

        public Viewport Viewport
        {
            get { return viewport; }
            set { viewport = value; }
        }

        #region "Conent Reader"

        public Map LoadMap(ContentManager Content, String strPath)
        {
            MapReader reader = new MapReader();
            map = reader.LoadMap(strPath);
            map.Texture = Content.Load<Texture2D>(System.IO.Path.Combine(@"Maps", map.TextureName));
            map.TilesPerRow = map.Texture.Width / map.TileSize.X;
            return map;
        }

        #endregion


        public void Draw(SpriteBatch spriteBatch, Rectangle worldArea)
        {

            int minX = Math.Max((int)Math.Floor((float)worldArea.Left / map.TileSize.X), 0);
            int maxX = Math.Min((int)Math.Ceiling((float)worldArea.Right / map.TileSize.Y), map.MapDimensions.X);

            int minY = Math.Max((int)Math.Floor((float)worldArea.Top / map.TileSize.X), 0);
            int maxY = Math.Min((int)Math.Ceiling((float)worldArea.Bottom / map.TileSize.Y), map.MapDimensions.Y);

            for (int x = minX; x < maxX; x++)
            {
                for (int y = minY; y < maxY; y++)
                {
                    Rectangle destinationRectangle = new Rectangle(x * map.TileSize.X, y * map.TileSize.Y, Map.TileSize.X, Map.TileSize.Y);
                    Point mapPosition = new Point(x, y);

                    Rectangle sourceRectangle =
                        Map.GetBaseLayerSourceRectangle(mapPosition);
                    if (sourceRectangle != Rectangle.Empty)
                    {
                        spriteBatch.Draw(Map.Texture, destinationRectangle,
                            sourceRectangle, Color.White);
                    }

                }
            }

        }


        public void DrawLayers(SpriteBatch spriteBatch, bool drawBase,
           bool drawFringe, bool drawObject, Rectangle worldArea)
        {
            // check the parameters
            if (spriteBatch == null)
            {
                throw new ArgumentNullException("spriteBatch");
            }
            if (!drawBase && !drawFringe && !drawObject)
            {
                return;
            }


            int minX = Math.Max((int)Math.Floor((float)worldArea.Left / map.TileSize.X), 0);
            int maxX = Math.Min((int)Math.Ceiling((float)worldArea.Right / map.TileSize.Y), map.MapDimensions.X);

            int minY = Math.Max((int)Math.Floor((float)worldArea.Top / map.TileSize.X), 0);
            int maxY = Math.Min((int)Math.Ceiling((float)worldArea.Bottom / map.TileSize.Y), map.MapDimensions.Y);

            for (int x = minX; x < maxX; x++)
            {
                for (int y = minY; y < maxY; y++)
                {
                    Rectangle destinationRectangle = new Rectangle(x * map.TileSize.X, y * map.TileSize.Y, Map.TileSize.X, Map.TileSize.Y);

                    // If the tile is inside the screen
                    //if (CheckVisibility(destinationRectangle))
                    {
                        Point mapPosition = new Point(x, y);
                        if (drawBase)
                        {
                            Rectangle sourceRectangle =
                                map.GetBaseLayerSourceRectangle(mapPosition);
                            if (sourceRectangle != Rectangle.Empty)
                            {
                                spriteBatch.Draw(map.Texture, destinationRectangle,
                                    sourceRectangle, Color.White);
                            }
                        }
                        if (drawFringe)
                        {
                            Rectangle sourceRectangle =
                                map.GetFringeLayerSourceRectangle(mapPosition);
                            if (sourceRectangle != Rectangle.Empty)
                            {
                                spriteBatch.Draw(map.Texture, destinationRectangle,
                                    sourceRectangle, Color.White);
                            }
                        }
                        if (drawObject)
                        {
                            Rectangle sourceRectangle =
                                map.GetObjectLayerSourceRectangle(mapPosition);
                            if (sourceRectangle != Rectangle.Empty)
                            {
                                spriteBatch.Draw(map.Texture, destinationRectangle,
                                    sourceRectangle, Color.White);
                            }
                        }
                    }
                }
            }
        }
        public void DrawColision(SpriteBatch spriteBatch, Rectangle worldArea, GraphicsDevice graphicsDevice)
        {
            // check the parameters
            if (spriteBatch == null)
            {
                throw new ArgumentNullException("spriteBatch");
            }
            Texture2D WhitePixel = new Texture2D(graphicsDevice, 1, 1);
            Color[] pixels = new Color[1 * 1];
            pixels[0] = Color.White;
            WhitePixel.SetData<Color>(pixels);

            int minX = Math.Max((int)Math.Floor((float)worldArea.Left / map.TileSize.X), 0);
            int maxX = Math.Min((int)Math.Ceiling((float)worldArea.Right / map.TileSize.Y), map.MapDimensions.X);

            int minY = Math.Max((int)Math.Floor((float)worldArea.Top / map.TileSize.X), 0);
            int maxY = Math.Min((int)Math.Ceiling((float)worldArea.Bottom / map.TileSize.Y), map.MapDimensions.Y);

            for (int x = minX; x < maxX; x++)
            {
                for (int y = minY; y < maxY; y++)
                {
                    Point mapPosition = new Point(x, y);
                    if (map.IsBlocked(mapPosition))
                    {
                        Rectangle destinationRectangle = new Rectangle(x * map.TileSize.X, y * map.TileSize.Y,
                                                                       Map.TileSize.X, Map.TileSize.Y);
                        spriteBatch.Draw(WhitePixel, destinationRectangle, new Color(Color.Crimson, 64));
                    }
                }
            }
        }

        //public static bool CheckVisibility(Rectangle screenRectangle)
        //{
        //    return ((screenRectangle.X > viewport.X - screenRectangle.Width) &&
        //        (screenRectangle.Y > viewport.Y - screenRectangle.Height) &&
        //        (screenRectangle.X < viewport.X + viewport.Width) &&
        //        (screenRectangle.Y < viewport.Y + viewport.Height));
        //}
    }
}
